perm filename WING[0,BGB] blob sn#073902 filedate 1973-11-29 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00017 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00006 00002	A SUMMARY OF WINGED EDGE OPERATIONS.
C00058 00003	The Winged Edge Operations.
C00063 00004	MIDPOINT EXAMPLE (see text on page 20).
C00065 00005	The Wing Link Operation.
C00070 00006	Part Tree Operations (continued).
C00074 00007	The Perimeter Fetch Operations.
C00078 00008	Euler Primitives.
C00099 00009	TWO EXAMPLES USING EULER PRIMITIVES. (see page 30).
C00102 00010	4. ENEW ← MKFE(V1,F,V2)
C00107 00011	Euler Primitives. (Continued).
C00112 00012	SOLID PRIMITIVES.
C00121 00013	
C00125 00014	IMAGE PRIMITIVES.
C00128 00015	
C00132 00016	GEOMED - a drawing program.
C00136 00017	
C00143 ENDMK
C⊗;
A SUMMARY OF WINGED EDGE OPERATIONS.


   DYNAMIC STORAGE ALLOCATION.

1.	Q ← MKNODE(SIZE);
2	KLNODE(Q);


   BFEV MAKE & KILL OPERATIONS.

1.	BNEW ← MKB(B);	 KLB(BNEW);
2.	FNEW ← MKF(B);	 KLF(B,FNEW);
3.	ENEW ← MKE(B);	 KLE(B,ENEW);
4.	VNEW ← MKV(B);	 KLV(B,VNEW);


   FETCH LINK AND STORE LINK OPERATIONS.

1.	F ← NFACE(Q); F ← PFACE(Q);  NFACE.(F,Q); PFACE.(F,Q);
2.	E ← NED(Q);   E ← NED(Q);    NED.(E,Q);   PED.(E,Q);
3.	V ← NVT(Q);   V ← NVT(Q);    NVT.(V,Q);   PVT.(V,Q);
4.	A ← NCW(E);   A ← PCW(E);    NCW.(A,E);   PCW.(A,E);
5.	A ← NCCW(E);  A ← PCCW(E);   NCCW.(A,E);  PCCW.(A,E);


   WING LINK OPERATIONS.

1.	WING(E1,E2);
2.	INVERT(E);


   PERIMETER FETCH OPERATIONS.

1.	E ← ECW(E,Q);
2.	E ← ECCW(E,Q);
3.	F ← FCW(E,V);
4.	F ← FCCW(E,V);
5.	V ← VCW(E,F);
6.	V ← VCCW(E,F);
7.	Q ← OTHER(E,Q);


   PARTS TREE OPERATIONS.

1.	B ← PART(B);	B ← COPART(B);
2.	B ← BODY(Q);	B ← SUPART(B);
3.	ATT(B1,B2);	ATTACH(B1,B2);
4.	DET(B);		DETACH(B);
The Winged Edge Operations.

BFEV Make & Kill Operations.

	Just  above  the  free storage routines are the four pairs of
make and kill operations. The MKB operation creates a body block  and
attaches it  as  a sub-part of the given body.  The world body always
exists so that MKB(WORLD) will make a body attached to the world.  In
this  paper,  the  terms `attach' and `detach' refer to operations on
the parts-tree linkages.   The FEV make operations:   MKF,  MKE,  MKV
create  the  corresponding  FEV  entities  and  place  them  in their
respective  FEV  rings  of  the  given  body.       In  the   current
implementation,  the  FEV makers set the type bits of the entity, and
increment the proper total FEV counter, as well as  the  proper  body
FEV  counter  in  the  given  body's node, (the Fcnt, Ecnt, Vcnt node
positions are shown in figure 2.3).  The kill operations:  KLB,  KLF,
KLE,  and KLV; delete the entity from its ring (or remove it from the
parts-tree), release its space by calling RELBLK, and then  decrement
the  appropriate  counters.   The body of the entity is needed by the
kill primitives and can be provide directly  as  an  argument  or  if
missing, will be found in the data by the primitive itself.

Fetch Link and Store Link Operations.

	Each of the fetch link and store link operations named in the
summary  is  a  single  machine   instruction   that   accesses   the
corresponding  link position in a node.   Once BFEV nodes exist, with
their rings and parts-tree already in place; the fetch and store link
operations are used to construct or modify a polyhedron's surface. At
this lowest level, constructing a polyhedron  requires  three  steps:
first  the two vertex and two face pointers are placed into each edge
in counter clockwise order as they appear when that  edge  is  viewed
from  the  exterior of the solid; second an edge pointer is placed in
each face and vertex, so that one can later get from a given face  or
vertex  to  one  of its edges; and third the edge wings are linked so
that all the ordered perimeter accessing operations  described  below
will work. Wing linking is facilitated by the WING operation.
MIDPOINT EXAMPLE (see text on page 20).

                 \  pvt  /
                  \     /
            nccw   \   /   pcw
                    \ /
                  V  ⊗
                     |
                ENEW |
                     | nvt
                VNEW ⊗
                     | pvt
                   E |
                     |
                     ⊗
                    / \
             ncw   /   \   pccw
                  /     \
                 /  nvt  \

INTEGER PROCEDURE MIDPOINT (INTEGER E);
BEGIN "MIDPOINT"
	INTEGER B,ENEW,VNEW,V1,V2;

α CREATE A NEW EDGE AND VERTEX;
	B ← BODY(E);
	VNEW ← MKV(B);
	ENEW ← MKE(B);

α GET VERTICES AND FACES CONNECTED TO EDGES;
	PVT.(PVT(E),ENEW);
	PVT.(VNEW,E);
	NVT.(VNEW,ENEW);
	PFACE.(PFACE(E),ENEW);
	NFACE.(NFACE(E),ENEW);

α GET EDGES CONNECTED TO VERTICES;
	IF PED(V)=E THEN PED.(ENEW,V);
	PED.(ENEW,VNEW);

α LINK THE WINGS TOGETHER;
	WING(NCCW(E),ENEW);WING(PCW(E),ENEW);
	NCW.(E,ENEW);PCCW.(E,ENEW);
	PCW.(ENEW,E);NCCW.(ENEW,E);

α PLACE VNEW AT MIDPOINT POSITION;
	V1 ← PVT(ENEW); V2 ← NVT(E);
	XWC(VNEW) ← (XWC(V1)+XWC(V2)) * 0.5;
	YWC(VNEW) ← (YWC(V1)+YWC(V2)) * 0.5;
	ZWC(VNEW) ← (ZWC(V1)+ZWC(V2)) * 0.5;
	RETURN(VNEW);
END "MIDPOINT";
The Wing Link Operation.

	The  WING  operation  stores edge pointers into edges so that
the face perimeters and vertex  perimeters  are  made;  and  so  that
surface  parity is preserved. Given two edges which have a vertex and
a face in common, the WING operation places the  first  edge  in  the
proper  relationship  (PCW,  NCCW,  NCW, or PCCW) with respect to the
second, and the second in the proper relationship with respect to the
first.  The  INVERT operation swaps the vertex, face, clockwise wing,
and counter clockwise wing pointers  of  an  edge.  INVERT  preserves
surface parity, but flips edge parity.

The Midpoint Example.

	In  figure  2.4 an example of how the operations given so far
could be used to code a midpoint  primitive  is  shown.  The  example
midpoint  primitive  takes  an  edge argument and splits it in two by
making a new edge and a new vertex  and  by  placing  them  into  the
polyhedron  with the topology shown in the diagram. Then the midpoint
locus is computed and the new vertex is return.  The  ALGOL  notation
used  is  SAIL,  which allows defining the character "α" as a COMMENT
delimiter and allows defining XWC as a real number from  the  special
array  named  MEMORY.  The  MEMORY  array in SAIL is the job's actual
machine memory space and gives the user the freedom of accessing  any
word in his core image.

The Parts-Tree Operations.

	As  shown  in  figure  2.1, each body node has two parts-tree
links named PART and COPART. The PART link is the head of a  list  of
sub-parts  of the body. When a body has no sub-parts the PART link is
the negative of that body's pointer;  that  is  the  body  points  at
itself.   When a body has parts, the first part is pointed at by PART
and the second is pointed at by the COPART link of the first  and  so
on  until  a negative pointer is retrieved which indicates the end of
the parts list. The negative pointer at  the  end  of  a  parts  list
points  back to the orginal body, which is the supra-part or "supart"
of all those bodies in that list.

	The parts may be accessed by its link names PART and  COPART.
Also  the  SUPART  of  a  body  returns the (positive) pointer to the
supart of a body. The BODY operation returns the body to which a face
edge  or  vertex  belongs;  this might be found by CDR'ing a FEV ring
until a body node is reached, but for the sake of speed each edge (as
shown  in  figure 2.3) has a PBODY link which points back to the body
to which the edge belongs, and since each face and vertex  points  at
an  edge, the body of an FEV entity can be retrieved by fetching only
one or two links.
Part Tree Operations (continued).

	The parts-tree is  altered  by  the  DET(B)  operation  which
removes  a body B from its supart and leaves it hanging free; and the
ATT(B1,B2) operation which places a free body B1 into the parts  list
of  a  body  B2. Since bodies are made attached to the world body and
generally  kept  attached  to  something,  two   further   parts-tree
operations  are  provided, compounding the first two in the necessary
manner.  The DETACH(B) operation DET's B from its current  owner  and
ATT's  it  to  the world; and the ATTACH(B1,B2) operation will DET B1
from its supart and attach it to a new supart.  In normal (one world)
circumstances one only needs to use ATTACH to build things.

Perimeter Fetch and Store Operations.

	There are seven perimeter fetch primitives, which when  given
an  edge  and  one  of its links will fetch another link in a certain
fashion.   Using the winged edge data structure these primitives  are
easily implemented  in a few machine instructions which test the type
bits and typically do one or  two  compares.  Clockwise  and  counter
clockwise  are  always  determined  from  the outside of a polyhedron
looking down on a particular face, edge or vertex.  I  apologize  for
the  high redundancy on the next page, but felt that it was necessary
to make the explanations independent for reference.


FIGURE 2.5 - Face Perimeter Accessing with respect to edge E.

	      VCCW(E,F) ⊗-------E-------⊗  VCW(E,F)
	                 \             /
	                  \     F     /
	              ECCW(E,F)   ECW(E,F)  
	                    \       /
	                     \     /
	                      \   /
			       \ /
			        ⊗


FIGURE 2.6 - Vertex Perimeter Accessing with respect to edge E.

				E
				|
		          	|          
		    FCCW(E,V)	|     FCW(E,V)
				⊗ V
		               / \
		              /   \
		             /     \
		            /       \
		    ECCW(E,V)       ECW(E,V)
The Perimeter Fetch Operations.


E ← ECW(E,F); Get Edge Clockwise from E about F's perimeter.
E ← ECCW(E,F); Get Edge Counter Clockwise from E about F's perimeter.

	Given an edge and a face belonging  to  that  edge,  the  ECW
fetch  primitive  returns  the  next  edge clockwise belonging to the
given face's perimeter and the ECCW fetch primitive returns the  next
edge counter clockwise belonging to the given face's perimeter.

E ← ECW(E,V); Get Edge Clockwise from E about V's perimeter.
E ← ECCW(E,V); Get Edge Counter Clockwise from E about V's perimeter.

	Given an edge and a vertex belonging to that  edge,  the  ECW
fetch  primitive  returns  the  next  edge clockwise belonging to the
given vertex's perimeter and the ECCW  fetch  primitive  returns  the
next   edge   counter  clockwise  belonging  to  the  given  vertex's
perimeter.

F ← FCW(E,V); Get the face clockwise from E about V.
F ← FCCW(E,V); Get the face counter clockwise from E about V.

	Given  an  edge  and a vertex belonging to that edge, the FCW
fetch primitive returns the face clockwise from the given edge  about
the  given  vertex  and  the  FCCW  fetch  primitive returns the face
counter clockwise from the given edge about the given vertex.

V ← VCW(E,F); Get the vertex clockwise from E about F.
V ← VCCW(E,F); Get the vertex counter clockwise from E about F.

	Given  an  edge  and  a  face belonging to that edge, the VCW
fetch primitive returns the vertex  clockwise  from  the  given  edge
about  the given face and the VCCW fetch primitive returns the vertex
counter clockwise from the given edge about the given face.

F ← OTHER(E,F); Get the other face of an edge.
V ← OTHER(E,V); Get the other vertex of an edge.

	Given  an  edge  and  one  face of that edge the OTHER fetch
primitive returns the other face belonging to  that  edge.  Given  an
edge  and  one  vertex of that edge the OTHER fetch primitive returns
the other vertex belonging to that edge.
Euler Primitives.

1. BNEW ← MKBFV;	Make Seminal Body.

	The  MKBFV  primitive  returns  a  body with one face and one
vertex and no edges. Other bodies are formed by  applying  primitives
to  the seminal MKBFV body. The seminal body is initially attached as
a part of the world.


2. KLBFEV(BNEW);	Kill Body and all its pieces.

	The  KLBFEV  primitive will detach and delete from memory the
body given as an argument as well as all its faces,  edges,  vertices
and sub-parts.


3. VNEW ← MKEV(F,V);	Make an edge and a vertex.

	The MKEV primitive takes a face, F, and a vertex, V,  of  F's
perimeter  and  it  creates a new edge, ENEW, and a new vertex, VNEW.
ENEW and VNEW are called a "wire spur" at V on F.  MKEV  returns  the
newly  made  vertex,  VNEW;  ENEW  can  be reached since PED(VNEW) is
always ENEW. Only one wire spur is allowed at V on F at a time.

	When applied to the face of a seminal body,  MKEV  forms  the
special  polyhedron called a "wire" and returns the new vertex as the
"negative" end of the wire.  A  wire  polyhedron  is  illustrated  in
figure  3.1. When applied to the negative end of a wire, MKEV extends
the wire; however if applied to any other vertex  of  the  wire, MKEV
refuses to change anything and merely returns its vertex argument.

 Figure 3.1 - A Wire Polyhedron.      Figure 3.2  -  VNEW←MKEV(F,V);

    seminal vertex ⊗ V1                          +V
    positive end  +|  of wire.                   /|\
                   | E1                         / |←←←←ENEW spur.
                  -|                           /  |  \
                   ⊗ V2                       / -VNEW \
                  +|                         /         \
                   | E2                     /     F     \
   negative end   -| of wirer              /             \
   latest vertex   ⊗ V3                   ⊗---------------⊗
TWO EXAMPLES USING EULER PRIMITIVES. (see page 30).

α MAKE A CUBE;
INTEGER PROCEDURE MKCUBE;
BEGIN "MKCUBE"
	INTEGER B,F,E,V1,V2,V3,V4;
α CREATE SEMINAL POLYHEDRON;
	B ← MKBFV;	F ← PFACE(B);	V1 ← PVT(B);
	XWC(V1)←+1;	YWC(V1)←+1;	ZWC(V1)←-1;
α MAKE SEMINAL POLYHEDRON INTO A LAMINA POLYHEDRON;
	V2 ← MKEV(F,V1);	XWC(V2)←-1;
	V3 ← MKEV(F,V2);	YWC(V3)←-1;
	V4 ← MKEV(F,V3);	XWC(V4)←+1;
	F  ← MKFE(V1,F,V4);
α MAKE FOUR SPURS ON THE LAMINA;
	V1 ← MKEV(F,V1);	ZWC(V1)←+1;
	V2 ← MKEV(F,V2);
	V3 ← MKEV(F,V3);
	V4 ← MKEV(F,V4);
α JOIN SPURS TO FORM FINAL FACES;
	E  ← MKFE(V1,F,V2);
	E  ← MKFE(V2,F,V3);
	E  ← MKFE(V3,F,V4);
	E  ← MKFE(V4,F,V1);
	RETURN(B);
END "MKCUBE";


α FORM A PYRAMID ON A FACE;
INTEGER PROCEDURE PYRAMID (INTEGER F);
BEGIN	"PYRAMID"
	INTEGER V,V0,E,E0,PEAK,EX;
	REAL X,Y,Z; INTEGER I;
	X←Y←Z←I←0;
α GET A VERTEX OF THE FACE AND MAKE A SPUR TO A PEAK;
	E←E0←PED(F);
	V0 ← VCW(E0,F);
	PEAK ← MKEV(F,V0);
α CONNECT THE OTHER VERTICES OF THE FACE TO THE PEAK;
	WHILE TRUE DO 
	BEGIN
		V ← VCCW(E,F);
		X←X+XWC(V);	Y←Y+YWC(V);	Z←Z+ZWC(V);
		INCREM(I);
		IF V=V0 THEN DONE;
		E ← ECCW(E,F);
		EX ← MKFE(PEAK,F,V);
	END;
α POSITION THE PEAK VERTEX AT THE CENTER OF THE FACE;
	XWC(PEAK)←X/I;	YWC(PEAK)←Y/I;	ZWC(PEAK)←Z/I;
	RETURN(PEAK);
END	"PYRAMID";
4. ENEW ← MKFE(V1,F,V2);

	The  MKFE primitive can be thought of as a face split.  Given
a face and two of  its  vertices,  MKFE  forms  a  new  face  on  the
clockwise  side  of  the  line  V1  to V2 leaving the old face on the
counter clockwise side. V1 becomes the PVT of ENEW,  V2  becomes  the
NVT  of  ENEW, F becomes the PFACE of ENEW and FNEW becomes the NFACE
of ENEW; also ENEW becomes the PED of F and FNEW.


Figure 3.3  -  MKFE and KLFE.

           BEFORE MKFE             AFTER ENEW←MKFE(V1,F,V2)
            ⊗       ⊗                     ⊗       ⊗             
           / \     / \                   / \     / \            
          /   \   /   \                 /   \   /   \           
         /     \ /     \               /     \ /     \          
        /       ⊗       \             /      +V1      \         
       /                 \           / -FNEW  |  +F    \        
      ⊗         F         ⊗         ⊗         |←←←ENEW  ⊗       
       \                 /           \        |        /        
        \       ⊗       /             \      -V2      /         
         \     / \     /               \     / \     /          
          \   /   \   /                 \   /   \   /           
           \ /     \ /                   \ /     \ /            
            ⊗       ⊗                     ⊗       ⊗             
       AFTER F←KLFE(ENEW);               BEFORE KLFE

	MKFE is also used to join  the two ends of a wire  polyhedron
to form a "lamina"; or the two ends of wire spurs to split a face; or
an end of a wire spur and a regular perimeter vertex to split a face.
A "lamina polyhedron" has only two faces and thus no volume.


EULER EXAMPLES.

	The use of the primitives discussed so far is illustrated  by
the  example  subroutines  in  figure  3.4  on page 29. The make cube
subroutine starts by placing a seminal vertex at (1,1,1); Then a wire
of three edges is made using the MKEV primitive. As the code implies,
MKEV places its new vertex at the locus of the old one.  The ends  of
the  wire  are joined with a MKFE to form a lamina polyhedron, then a
spur is placed on each of the vertices of the lamina, and finally the
spurs are joined.

	The  pyramid  example  is more realistic, since polyhedra are
not generated ex nihil, but rather arise out of the  vision  routines
and  the geometric editor. PYRAMID takes a face as an argument (which
is assumed to have no spurs) and runs a spur from one vertex  to  the
middle  of the faces, then all the remaining vertices of the face are
joined to that spur to form a pyramid.
Euler Primitives. (Continued).

5. VNEW ← ESPLIT(E);	Edge Split.

	This  primitive  splits  an edge by making a new vertex and a
new edge. Its implementation is very similar to the midpoint  example
on page 19. ESPLIT is heavily used in the hidden line eliminator.

6. F ← KLFE(ENEW);	Kill Face Edge.

	This primitive Kills a face and an  edge  leaving  one  face.
Since  this primitive is intended to be an inverse of MKFE, the NFACE
of ENEW is killed. However the NFACE and PFACE  of  an  edge  may  be
swapped by using the INVERT(E) primitive. See Figure 3.3 for KLFE.

7. E ← KLEV(VNEW);	Kill Edge Vertex.

	This primitive kills an edge and a vertex leaving  one  edge.
This primitive will eliminate spurs made with MKEV and midpoints made
with ESPLIT; in a pure form it would have to leave  vertices  with  a
valence  greater than two untouched, however it in fact "un-pyramids"
them with a series of KLFE's and then kills the remaining spur.

8. V ← KLVE(ENEW);	Kill Vertex Edge.

	This primitive kills a vertex and an edge leaving one vertex.
This primitive is the face-vertex dual of  KLFE,  namely  instead  of
killing  NFACE  of  E and fixing up PFACE's perimeter, KLEV kills the
NVT of E and fixes up PVT of E's perimeter.


9. B ← GLUE(F1,F2);	Glue two faces.

	This  primitive glues two faces together forming one new body
out of two old ones (the body of F1 survives) or forming a handle  on
the given body. The number of edges in the two faces must be the same
and their orientation should be opposite (exterior to exterior).

*10. BNEW ← UNGLUE(E);	Unglue along seam.	*not implemented.

	This  primitive  unglues  along  the  seam  containing E. The
UNGLUE primitive requires that a loop of edges be marked as a  "seam"
along  which unglue will form two opposite faces.  The marks are made
in the temporary type bit in the edge nodes of the  given  body.   If
the  cut  forms  two  disjoint  bodies then a new body is made on the
NFACE side of the original E argument.
SOLID PRIMITIVES.

1. VPEAK ← PYRAMID(F);
2. F ← PRISM(F);
3. F ← CWPRISMIOD(F);
4. F ← CCWPRISMIOD(F);

	These  four  primitives  are  called  the "sweep primitives",
because they form a simple polyhedron from a face in a  fashion  that
appears  like sweeping the face along. The sweep primitives (with the
exception of PYRAMID) do not change the location of  the  given  face
but  merely  copy  its perimeter, forming new faces and edges between
the old perimeter and the new perimeter.  The pyramid  primitive  has
already appeared as an example on page 29.

	Starting with a nine sided face lamina, the rocket in  figure
3.5 was formed from the bottom by sweeping two prism stages, then two
counter clockwise prismoid stages, and then  two  clockwise  prismoid
stages,  and finally one pyramid to form the nose cone. The fins were
made by prism sweeping every third face of the first stage.

5. ROTCOM(F);	Rotation Completion.

	As illustrated in the first three frames of figure 3.7 below,
wire faces can be swept to form a shell. When a wire face is swept by
a  sweep  primitive (other than pyramid) it is marked as a shell face
of rotation and its original perimeter count is kept for later sweeps
to  refer  to.    In the third frame the shell has been positioned so
that its slot can be seen. The shell face now includes all the  edges
of  both  pole  caps as well as the two meridians of the slot. ROTCOM
takes such a shell face and breaks it into two  polar  faces  and  as
many other faces as necessary, by means of the count that was saved.

6. FVDUAL(B);
7. BNEW←MKCOPY(B);

	These two primitives illustrate the extremes from a class  of
miscellaneous  primitives.  FVDUAL is a worthless curosity and MKCOPY
is quite useful but uninteresting. FVDUAL(B) of a  body  changes  all
the faces of a body into vertices and all the vertices into faces, in
the winged edge data structure this merely requires computing a locus
for  each face (its center), re-"typing" faces and vertices, and then
swapping the face and vertex link positions in each  face,  edge  and
vertex of the body.

	Figure   3.8   illustrates   Euclid's   construction   of   a
dodecahedron from a cube. The unit cube is formed, then all its edges
are  midpointed  and  translated  0.2  units  into the three pairs of
parallel faces; then the midpoints are lifted 0.3 units off the plane
of each face of the cube; then MKFE is applied six times to split the
eight sided faces  into  five  sided  faces;  giving  a  dodecahedron
(nearly  regular). Applying the FVDUAL to the dodecahedron yields the
icosahedron.

8.  EVERT(B);
9.  B1←BUN(B1,B2);
10. B1←BIN(B1,B2);

	These  three  primitives  perform  the  Boolean operations on
polyhedron interior volumes. EVERT(B) turns a body inside  out,  thus
changing  a cube into a room, as a solid into a bubble.  Objects with
infinite "interiors" are permissible; such polyhedra  are  impossible
in  many  classical  developements  of  solid Geometry which make the
interior of a polyhedron to  be  the  region  of  space  with  finite
volume,  by  definition.  The  body  union is BUN, which allows B1 to
survive if the interiors of the bodies are not disjoint. A body  with
two  disjoint  polyhedrons  is shunned. The body intersection is BIN,
which allows B1 to survive if the interiors of  the  bodies  are  not
disjoint.
IMAGE PRIMITIVES.

     1.	PROJECTOR(CAMERA,WORLD);
     2.	ELIST←CLIPER(WINDOW,WORLD);
     3.	OCCULT(WORLD);
*    4.	SHADOW(SUN,WORLD);
*    5.	TV ← MKVID(WINDOW,WORLD);
*    6.	B2D ← MKB2D(WINDOW,WORLD);
*    7.	B2D ← CAREYE(TV);

	The single  application around  which the geometric  modeling
of  this paper  is being  built is for  a computer  television vision
system  for looking at  real world scenes.  I believe that  a
computer must  have a means  of representing  what it is  intended to
see  and further that the representation  must have (in principle) an
inverse relation to a television  image.  My first premise  is rarely
questioned,  the  second  premise  is  frequentlty questioned.

One
alternative position is  that so called  "features" can be  extracted
from an image and then used by a heuristic  problem solver to find an
association  between  the  perceived  features  and previous  general
knowledge; it is  then stated that there  is no need  to go from  the
general knowledge  or even from  the so called image  "features" back
down  to a television image, even just  in principle. I wish to state
the opposite,  there is a need to go  from the general representation
to  a television image  in order  to develop computer  vision without
having to solve  several other problems  of Artificial  Intelligence.

Applications  of  geometric modeling  other  than  television  vision
might   include:  architectural  design,   computer  animation,  and
mechanical drawing.
GEOMED - a drawing program.

	GEOMED,  Geometric  Model  Editor,  is for making and editing
polyhedra.  The  command  language  of  GEOMED  provides  the   Euler
primitives  in  the  context  of  a  push  down stack (the PADPDL) of
bodies, faces, edges and vertices. The  main  difference  between  an
interactive  program and a programming language being that the former
carries along a working context so that most arguments  and  data  do
not have to be explicitly named.

	V	-	make seminal vertex body.
	E	-	make edge and vertex.
	J	-	make edge and face.
	G	-	glue two faces.

	In addition to the stack, GEOMED provides frames of reference
for  the  Euclidean  transformations;  there  is  a world frame, body
frames, camera frames, relative frame  and  face  frames.   Also  the
strength  of  a Euclidean transformation can be halved or double, set
directly or entered  numerically  in  several  kinds  of  units.  And
finally  the transformation can be done once or repeatedily by keying
chords of Stanford's extra shift keys named "control" and "meta" with
a  ;  :  ( ) - or * character. These characters are not mnemonics but
were chosen because of thier positions on the keyboard.

	: ;	-	transform about X-axis.
	( )	-	transform about Y-axis.
	- *	-	transform about Z-axis.

		no shifts     -	TRANSLATION.
	α   -	control       -	ROTATION.
	β   -	meta          -	DILATION.
	ε   -	meta-control  -	REFLECTION.

	Finally,  GEOMED  provides access to all the solid primitives
and hidden line elimination,  along  with  commands  for  the  stack,
input,  output,  display,  and  switch  toggling.    The commands are
detailed in the operating note,  SAILON-68,  along  with  a  list  of
GEOMES  and  GEOMEL  subroutines.    Two  examples  should suffice to
illustrate how concise and illegible GEOMED command strings are:

1.	V:)\E;E(E:J↑/*S-↑		forms a cube.
2.	V:@E*E*E*E*E*E*E*J↑!
	\\:@S)S)S)S)S)S)S)S)G↑		forms a torus.

Thus  a polyhedron can be represented in a few characters (which must
be  compiled);  one  might  hope  that  such  a  "representation   by
generation"  could  provide  a  link  between  semantic and geometric
models. The hard direction is to get from a polyhedron model  to  the
command string.